import store from '@/store/index.ts';
import Layout from '@/layouts/index.vue';
import ParentView from '@/components/ParentView/index.vue';
import { getRouters } from '@/api/system/menu.ts';
import auth from '@/plugins/modules/auth.ts';
import { dynamicRoutes, staticRoutes } from '@/router/routes.ts';
import { router } from '@/router/index.ts';
import InnerLink from '@/components/InnerLink/index.vue';

// 引入需要异步加载的页面模块集合（异步组件）
const pageModules = import.meta.glob('@/views/**/*.vue');

export const usePermissionStore = defineStore('permission', () => {
  const state = reactive<{
    routes: any[];
    addRoutes: any[];
    defaultRoutes: any[];
    topbarRouters: any[];
    sidebarRouters: any[];
  }>({
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: [],
  });

  const SET_ROUTES = (routes: any[]) => {
    state.addRoutes = routes;
    state.routes = staticRoutes.concat(routes);
  };
  const SET_DEFAULT_ROUTES = (routes: any[]) => {
    state.defaultRoutes = staticRoutes.concat(routes);
  };
  const SET_TOPBAR_ROUTES = (routes: any[]) => {
    state.topbarRouters = routes;
  };
  const SET_SIDEBAR_ROUTERS = (routes: any[]) => {
    state.sidebarRouters = routes;
  };

  // 生成路由
  function GenerateRoutes() {
    return new Promise((resolve) => {
      // 向后端请求路由
      getRouters().then((res) => {
        const sdata = JSON.parse(JSON.stringify(res));
        const rdata = JSON.parse(JSON.stringify(res));
        const sidebarRoutes = filterAsyncRouter(sdata);
        const rewriteRoutes = filterAsyncRouter(rdata, false, true);
        const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
        asyncRoutes.forEach((item) => {
          router.addRoute(item);
        });
        SET_ROUTES(rewriteRoutes);
        SET_SIDEBAR_ROUTERS(staticRoutes.concat(sidebarRoutes));
        SET_DEFAULT_ROUTES(sidebarRoutes);
        SET_TOPBAR_ROUTES(sidebarRoutes);
        resolve(rewriteRoutes);
      });
    });
  }

  return {
    ...toRefs(state),
    GenerateRoutes,
  };
});

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(asyncRouterMap: Array<any>, lastRouter = false, type = false) {
  return asyncRouterMap.filter((route) => {
    if (type && route.children) {
      route.children = filterChildren(route.children);
    }
    if (route.component) {
      if (route.component === 'Layout') {
        route.component = Layout;
      } else if (route.component === 'ParentView') {
        route.component = ParentView;
      } else if (route.component === 'InnerLink') {
        route.component = InnerLink;
      } else {
        route.component = loadView(route.component);
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type);
    } else {
      delete route['children'];
      delete route['redirect'];
    }
    return true;
  });
}

function filterChildren(childrenMap: Array<any>, lastRouter: any = false) {
  let children: any[] = [];
  childrenMap.forEach((el, index) => {
    if (el.children && el.children.length) {
      if (el.component === 'ParentView' && !lastRouter) {
        el.children.forEach((c: any) => {
          c.path = el.path + '/' + c.path;
          if (c.children && c.children.length) {
            children = children.concat(filterChildren(c.children, c));
            return;
          }
          children.push(c);
        });
        return;
      }
    }
    if (lastRouter) {
      el.path = lastRouter.path + '/' + el.path;
    }
    children = children.concat(el);
  });
  return children;
}

// 动态路由遍历，验证是否具备权限
export function filterDynamicRoutes(routes: any[]) {
  const res: any[] = [];
  routes.forEach((route) => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route);
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route);
      }
    }
  });
  return res;
}

// 异步组件加载方法匹配
export const loadView = (view: any) => {
  for (const pageModuleKey in pageModules) {
    if (pageModuleKey.includes(view)) {
      return pageModules[pageModuleKey];
    }
  }
};

// 在组件外部用pinia就调用这个方法
export function usePermissionStoreWithOut() {
  return usePermissionStore(store);
}
